#include "Character.h"
#include "WSSocket.h"
#include "tinyxml/tinyxml.h"
#include "StringConverter.h"
#include "VipCardManager.h"
#include "OpcodesEx.h"
#include "GameDefine.h"
#include "Tools.h"
#include LOGIC_MGR_PATH
#include ENUM_PATH

#define VIP_MAX_ID	599
// //-----------------------------------------------------------------------
// void register_vip_process()
// {
	// // 获取VIP勋章数据
	// mgr->register_server_process(CMSG_GETVIPHONORDATA,script_world_process_getviphonoricon);
	// Log.Debug("World Process", "Register opcode 0x%02x Process:[%s]",CMSG_GETVIPHONORDATA,"script_world_process_getviphonoricon");
	// // 获取VIP勋章剩余时间
	// mgr->register_server_process(CMSG_GETVIPHONORDATA,script_world_process_getviphonorlefttime);
	// Log.Debug("World Process", "Register opcode 0x%02x Process:[%s]",CMSG_GETVIPHONORDATA,"script_world_process_getviphonorlefttime");
// }
//-----------------------------------------------------------------------
VipCardManager::VipCardManager()
{
	LoadVipCards();
	LoadLuckyExpsXml();
}
//-----------------------------------------------------------------------
VipCardManager::~VipCardManager()
{}
//--------------------------------------------------------
bool VipCardManager::LoadVipCards()
{
	TiXmlDocument doc("../scripts_xml/vipcards.xml");
	if(!doc.LoadFile())
	{
		Log.Error("VipCardManager::LoadVipCards", "load vipcards.xml failed!");
		return false;
	}
	TiXmlElement* pRoot = doc.RootElement();
	if (NULL == pRoot)
	{
		Log.Error("VipCardManager::LoadVipCards", "vipcards.xml have not root node!");
		return false;
	}
	VIPCard vipCard;
	while(pRoot)
	{
		if (pRoot->HasAttribute("id")){// id
			vipCard.id = StringConverter::parseUnsignedInt(pRoot->Attribute("id"));
		}
		if (pRoot->HasAttribute("name")){// 名称
			vipCard.name = pRoot->Attribute("name");
		}
		if (pRoot->HasAttribute("type")){// 类型
			vipCard.type = StringConverter::parseUnsignedInt(pRoot->Attribute("type"));
		}
		if (pRoot->HasAttribute("coins")){// 铜钱
			vipCard.coins = StringConverter::parseUnsignedInt(pRoot->Attribute("coins"));
		}
		if (pRoot->HasAttribute("money")){// 金币
			vipCard.money = StringConverter::parseUnsignedInt(pRoot->Attribute("money"));
		}
		if (pRoot->HasAttribute("bugle")){// 喇叭
			vipCard.bugle = StringConverter::parseUnsignedInt(pRoot->Attribute("bugle"));
		}
		if (pRoot->HasAttribute("diamand")){// 钻石房卡
			vipCard.diamand = StringConverter::parseUnsignedInt(pRoot->Attribute("diamand"));
		}
		if (pRoot->HasAttribute("signin")){
			vipCard.signin = StringConverter::parseUnsignedInt(pRoot->Attribute("signin"));
		}
		if (pRoot->HasAttribute("days")){
			vipCard.days = StringConverter::parseUnsignedInt(pRoot->Attribute("days"));
		}
		if (pRoot->HasAttribute("flag")){
			vipCard.flag = StringConverter::parseUnsignedInt(pRoot->Attribute("flag"));
		}
		if (pRoot->HasAttribute("loginAdd")){
			vipCard.lgAdd = StringConverter::parseUnsignedInt(pRoot->Attribute("loginAdd"));
		}
		if (pRoot->HasAttribute("jjAdd")){
			vipCard.jjAdd = StringConverter::parseUnsignedInt(pRoot->Attribute("jjAdd"));
		}
		if (pRoot->HasAttribute("hongbao")){
			vipCard.hongbao = StringConverter::parseUnsignedInt(pRoot->Attribute("hongbao"));
		}
		if (pRoot->HasAttribute("abate")){
			vipCard.abate = StringConverter::parseUnsignedInt(pRoot->Attribute("abate"));
		}
		if (pRoot->HasAttribute("brow")){
			vipCard.brow = StringConverter::parseUnsignedInt(pRoot->Attribute("brow"));
		}
		if (pRoot->HasAttribute("is2exp")){
			vipCard.b2Exp = StringConverter::parseBool(pRoot->Attribute("is2exp"));
		}
		if (pRoot->HasAttribute("isShow")){
			vipCard.bShow = StringConverter::parseBool(pRoot->Attribute("isShow"));
		}
		if (pRoot->HasAttribute("morra")){
			vipCard.morraNum = StringConverter::parseUnsignedInt(pRoot->Attribute("morra"));
		}
		if (pRoot->HasAttribute("key")){
			vipCard.key = pRoot->Attribute("key");
		}
		if (pRoot->HasAttribute("vip_id")){
			vipCard.vip_id = StringConverter::parseUnsignedInt(pRoot->Attribute("vip_id"));
		}
		if (pRoot->HasAttribute("vip_day")){
			vipCard.vip_day = StringConverter::parseUnsignedInt(pRoot->Attribute("vip_day"));
		}
		
		m_mapVipCards.insert(std::make_pair(vipCard.id, vipCard));
		pRoot = pRoot->NextSiblingElement();
	}
	Log.Debug("VipCardManager::LoadVipCards:", "load vipcards.xml successfully!");
	return true;
}
//--------------------------------------------------------
bool VipCardManager::ReloadVipCards()
{
	WGS_VIP_WRITE_LOCK
	m_mapVipCards.clear();
	LoadVipCards();
	return true;
}


bool VipCardManager::LoadLuckyExpsXml()
{
	char strPath[512] = "";
	sprintf(strPath, "../scripts_xml/lucky_levels.xml");
	TiXmlDocument doc(strPath);

	if(!doc.LoadFile())
	{
		Log.Error("load level and exp", "load lucky_levels.xml failed!");
		return false;
	}
	TiXmlElement* pRoot = doc.RootElement();
	if (NULL == pRoot)
	{
		Log.Error("load level and exp", "lucky_levels.xml have not root node!");
		return false;
	}
	if (String(pRoot->Value()).compare("levels"))
	{
		Log.Error("load level and exp", "lucky_levels.xml's root node is error!");
		return false;
	}
	
	m_mapLuckyExps.clear();
	TiXmlElement* pChild = pRoot->FirstChildElement();
	while(pChild != NULL)
	{
		uint8 level = atoi(pChild->Attribute("lv"));
		uint32 exp = atoi(pChild->Attribute("exps"));
		m_mapLuckyExps.insert(std::make_pair(level, exp));
		pChild = pChild->NextSiblingElement();
	}
	
	Log.Debug("XmlDataManager::InitLevelExpList:", "load lucky_levels.xml successfully! m_mapLuckyExps[%u]", m_mapLuckyExps.size());
	return true;
}

bool VipCardManager::ReLoadLuckyExpsXml()
{
WGS_VIP_WRITE_LOCK
	m_mapLuckyExps.clear();
	return LoadLuckyExpsXml();
}

// 得到玩家当前幸运等级
const uint8 VipCardManager::GetCurrentLuckyLevel(const uint32 & exps,uint32 & currExps)
{
WGS_VIP_WRITE_LOCK
	if(!exps)
		return 0;
	
	uint8 lv = 1;
	uint32 nextLevelExps = GetLuckyNextLevelExps(lv);
	currExps = exps;
	
	while(currExps >= nextLevelExps)
	{
		if(lv >= GetLuckyExpMaxLevel())
		{
			lv = GetLuckyExpMaxLevel();
			currExps = 0;
			break;
		}
		
		currExps -= nextLevelExps;
		++lv;
		nextLevelExps = GetLuckyNextLevelExps(lv);
	}
	
	return lv;
}

// 得到下一级幸运值升级点数
const uint32 VipCardManager::GetLuckyNextLevelExps(const uint8 level)
{
	std::map<uint8, uint32>::const_iterator iter = m_mapLuckyExps.find(level);
	if (iter != m_mapLuckyExps.end())
		return iter->second;
	
	return 0;
}

// 得到幸运值最大等级
const uint8 VipCardManager::GetLuckyExpMaxLevel()
{
	return m_mapLuckyExps.size();
}

//--------------------------------------------------------
VIPCard VipCardManager::GetVipCard(const uint32 id)
{
	WGS_VIP_READ_LOCK
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.find(id);
	if (iter != m_mapVipCards.end())
		return iter->second;
	return VIPCard();
}
//--------------------------------------------------------
void VipCardManager::GetUsedVipCardsList(CharPtr &pChr, std::list<VIPCard> &lstVipCards)
{
	WGS_VIP_READ_LOCK
	uint32 curTime = time(0);
	uint32 maxVipId = 0; // 最高vip等级
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		uint32 endTime = 0;
		if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > curTime)
		{
			if (1 == iter->second.type)
				maxVipId = iter->first;
			else
				lstVipCards.push_back(iter->second);
		}
		
	}
	if (maxVipId)
	{
		if(maxVipId >= 551 && maxVipId <= VIP_MAX_ID)
		{
			maxVipId = (maxVipId % 10 + 500);
		}
		lstVipCards.push_back(m_mapVipCards.find(maxVipId)->second);
	}
}
//-----------------------------------------------------------------------
bool VipCardManager::GetUsedVip(CharPtr &pChr, VIPCard &vipCard)
{
	WGS_VIP_READ_LOCK
	uint32 curTime = time(0);
	uint32 maxVipId = 0; // 最高vip等级
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (1 == iter->second.type)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > curTime)
				maxVipId = iter->first;
		}
	}
	if (maxVipId)
	{
		if(maxVipId >= 551 && maxVipId <= VIP_MAX_ID)
		{
			maxVipId = (maxVipId % 10 + 500);
		}
		
		vipCard = m_mapVipCards.find(maxVipId)->second;
		return true;
	}
	else
		return false;
}
//-----------------------------------------------------------------------
void VipCardManager::AddNewVIPInfo(CharPtr &pChr, VIPCard &vipCard)
{
	if (pChr.isNull())
		return;
	
	if(vipCard.id >= 551 && vipCard.id <= VIP_MAX_ID)
	{
		vipCard.id = (vipCard.id % 10 + 500);
	}
	
	uint32 addTime = vipCard.days * 24 * 3600;
	// 添加vip、勋章到期日期数据
	AddVIPDate(pChr, vipCard.key, addTime);
	// vip附加属性
	if (en_VipType_Authority != vipCard.type)
	{
		// 双倍经验
		if (vipCard.b2Exp)
			AddVIPDate(pChr, VIPEXPSDATE, addTime);
		// 礼包打折
		if (vipCard.abate)
			AddVIPDate(pChr, VIPABATEDATE, addTime);
	}
	
	// 猜拳次数
	if (vipCard.morraNum)
	{
		AddVipValue(pChr, VIPMORRANUM, vipCard.morraNum);
		WSSocketPtr pSocket = pChr->getSocket();
		if(pSocket.isNull())
			return;
		WorldPacket newP;
		if(CreateUpdateMorraNum(&newP, pChr))
			pSocket->SendPacket(&newP);
	}
	
	// 更新VIP勋章图标
	if (vipCard.bShow)
		UpdateVIPData(pChr);
}
//-----------------------------------------------------------------------
void VipCardManager::AddVIPDate(CharPtr &pChr, const String key, const uint32 addTime)
{
	if (pChr.isNull() || key == "" || addTime == 0)
		return;
	uint32 curTime = time(0);
	if (pChr->user_data.isPresented(key))
	{
		uint32 endTime = 0;
		if (pChr->user_data.Get<uint32>(key, endTime) && endTime > curTime)
			endTime += addTime;
		else
			endTime = curTime + addTime;
		endTime = sTools.FormatDataCeil(endTime);
		pChr->user_data.Set<uint32>(key, endTime); 
	}
	else
	{
		uint32 endTime = sTools.FormatDataCeil(curTime + addTime);
		pChr->user_data.New<uint32>(key, endTime); 
	}
}
//-----------------------------------------------------------------------
void VipCardManager::UpdateVIPValue(CharPtr &pChr, const String &key, const uint32 value)
{
	if (pChr.isNull())
		return;
	if (pChr->user_data.isPresented(key))
		pChr->user_data.Set<uint32>(key, value); 
	else
		pChr->user_data.New<uint32>(key, value); 
}
//-----------------------------------------------------------------------
void VipCardManager::AddVipValue(CharPtr &pChr, const String &key, const uint32 value)
{
	if (pChr.isNull())
		return;
	if (pChr->user_data.isPresented(key))
	{
		uint32 v = 0;
		pChr->user_data.Get<uint32>(key, v);
		pChr->user_data.Set<uint32>(key, v + value);
	}
	else
		pChr->user_data.New<uint32>(key, value); 	
}
//-----------------------------------------------------------------------
void VipCardManager::UpdateVIPDate(CharPtr &pChr)
{
	bool bUpdate = false;
	{
		WGS_VIP_READ_LOCK
		uint32 curTime = time(0);
		std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
		for (; iter != m_mapVipCards.end(); ++iter)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > 0 && endTime <= curTime)
			{
				pChr->user_data.Set<uint32>(iter->second.key, 0);
				if (iter->second.bShow)
					bUpdate = true;
			}
		}
	}
	if (bUpdate)
		UpdateVIPData(pChr);
}
//-----------------------------------------------------------------------
const uint32 VipCardManager::GoodsCutPrice(CharPtr &pChr, const uint32 price)
{
	if (!pChr.isNull())
	{
		uint32 endTime = 0;
		if (pChr->user_data.Get<uint32>(VIPABATEDATE, endTime) && endTime > time(0))
		{
			uint32 abate = 1;
			// 优先检测vip
			VIPCard vipCard;
			if (GetUsedVip(pChr, vipCard))
				abate = vipCard.abate;
			else
			{
				// 获取折扣卡
				std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.find(511);
				abate = iter->second.abate;
			}
			return (uint32)ceil(price * abate * 0.01);
		}
	}
	return price;
}
//-----------------------------------------------------------------------
void VipCardManager::AddExps(CharPtr &pChr, uint32 &exps)
{
	if (pChr.isNull())
		return;
	uint32 endTime = 0;
	if (pChr->user_data.Get<uint32>(VIPEXPSDATE, endTime) && endTime > time(0))
		exps *= 2;
}
//-----------------------------------------------------------------------
void VipCardManager::AddLoginGift(CharPtr &pChr, uint32 &coins)
{
	if (pChr.isNull())
		return;
	VIPCard vipCard;
	if (GetUsedVip(pChr, vipCard))
		coins += vipCard.lgAdd;
}
//-----------------------------------------------------------------------
void VipCardManager::AppendSubsidyGift(CharPtr &pChr, uint32 &coins)
{
	if (pChr.isNull())
		return;
	VIPCard vipCard;
	if (GetUsedVip(pChr, vipCard))
		coins += vipCard.jjAdd;
}
//-----------------------------------------------------------------------
void VipCardManager::PacketVipInfo(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet || pChr.isNull())
		return;
	std::list<VIPCard> lstVipCards;
	GetUsedVipCardsList(pChr, lstVipCards);
	uint32 offset = packet->size();
	uint8 num = lstVipCards.size();
	*packet << uint8(0); // 数量
	std::list<VIPCard>::iterator iter = lstVipCards.begin();
	for (iter = lstVipCards.begin(); iter != lstVipCards.end(); ++iter)
	{
		*packet << uint32((*iter).id); // id
		uint32 v = 0;
		pChr->user_data.Get<uint32>((*iter).key, v);
		*packet	<< v; // 剩余时间
	}
	if (sGLMgr.BeHadMammonCard(pChr))
	{
		*packet << uint32(ItemModel_Mammon) // 财神卡模式ID
				<< uint32(sGLMgr.GetItemNum(pChr,ItemModel_Mammon)); // 数量
		++num;
	}
	// 幸运卡
	std::list<ItemPtr> lstLucks;
	sGLMgr.GetLuckCardList(pChr, lstLucks);
	std::list<ItemPtr>::iterator iterLuck = lstLucks.begin();
	for(; iterLuck != lstLucks.end(); ++iterLuck)
	{
		*packet << uint32((*iterLuck)->model->getHandle()) // 模式ID
				<< uint32((*iterLuck)->getUInt32Field("num")); // 剩余点数
		++num;
	}
	
	uint32 lucky_exps = 0;
	if(pChr->user_data.isPresented("LUCKY_EXPS"))
		pChr->user_data.Get<uint32>("LUCKY_EXPS", lucky_exps);
	
	if(lucky_exps)
	{
		uint32 curr_exps = 0;
		uint8 lv = GetCurrentLuckyLevel(lucky_exps,curr_exps);
		
		uint32 jindu = 10000;
		if(lv < GetLuckyExpMaxLevel())
		{
			jindu = uint32(uint32(float(curr_exps) / float(GetLuckyNextLevelExps(lv)) * 10000));
		}
		
		//陈綦制定的数据 说是这样处理协议比较简单 10000+lv  等级  第二个数据发送 进度条 2013-06-21 14:44
		*packet << uint32(10000+lv)
				<< uint32(jindu);
		++num;
	}
	
	packet->SetOffset(offset, num);
}
//-----------------------------------------------------------------------
void VipCardManager::PacketVipIcon(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet || pChr.isNull())
		return;
	std::list<VIPCard> lstVipCards;
	GetUsedVipCardsList(pChr, lstVipCards);
	uint32 offset = packet->size();
	*packet << uint8(0); // 数量	
	uint8 num = lstVipCards.size();
	std::list<VIPCard>::iterator iter = lstVipCards.begin();
	for (iter = lstVipCards.begin(); iter != lstVipCards.end(); ++iter)
	{
		*packet << uint32((*iter).id); // 勋章ID
	}
	if (sGLMgr.BeHadMammonCard(pChr))
	{
		*packet << uint32(ItemModel_Mammon); // 财神卡模式ID
		++num;
	}
	// 幸运卡
	std::list<ItemPtr> lstLucks;
	sGLMgr.GetLuckCardList(pChr, lstLucks);
	std::list<ItemPtr>::iterator iterLuck = lstLucks.begin();
	for(; iterLuck != lstLucks.end(); ++iterLuck)
	{
		*packet << uint32((*iterLuck)->model->getHandle()); // 模式ID
		++num;
	}
	
	uint32 lucky_exps = 0;
	if(pChr->user_data.isPresented("LUCKY_EXPS"))
		pChr->user_data.Get<uint32>("LUCKY_EXPS", lucky_exps);

	if(lucky_exps)
	{
		uint32 curr_exps = 0;
		uint8 lv = GetCurrentLuckyLevel(lucky_exps,curr_exps);
		
		//陈綦制定的数据 说是这样处理协议比较简单 10000+lv  等级  第二个数据发送 进度条 2013-06-21 14:44
		*packet << uint32(10000+lv);
		++num;
	}
	
	packet->SetOffset(offset, num);
}
//-----------------------------------------------------------------------
bool VipCardManager::CreateGetVipIconPacket(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(64);
	packet->SetOpcode(SMSG_GETVIPHONORICON);
	*packet << uint16(SMSG_GETVIPHONORICON) << uint16(0);
	PacketVipIcon(packet,pChr);
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool VipCardManager::CreateUpdateVipDataPacket(WorldPacket * packet, CharPtr &pChr)
{
	if (!packet || pChr.isNull())
		return false;
	packet->clear();
	// 预开辟空间
	packet->reserve(64);
	packet->SetOpcode(SMSG_UPDATEVIPDATA);
	*packet << uint16(SMSG_UPDATEVIPDATA) << uint16(0);
	PacketVipInfo(packet,pChr);
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
void VipCardManager::UpdateVIPData(CharPtr &pChr)
{
	if (pChr.isNull())
		return;
	WorldPacket packet;
	if (CreateUpdateVipDataPacket(&packet, pChr))
	{
		WSSocketPtr socket = pChr->getSocket();
		if(!socket.isNull())
			socket->SendPacket(&packet);
	}
}
//-----------------------------------------------------------------------
void VipCardManager::AddVipInfo(CharPtr &pChr, VIPCard &vipCard, const uint32 endTime)
{
	if (pChr.isNull())
		return;
	// 添加vip、勋章到期日期数据
	UpdateVIPValue(pChr, vipCard.key, endTime);
	// vip附加属性
	if (2 != vipCard.type)
	{
		// 双倍经验
		if (vipCard.b2Exp)
			AddVIPDate(pChr, VIPEXPSDATE, endTime-time(0));
		// 礼包打折
		if (vipCard.abate)
			AddVIPDate(pChr, VIPABATEDATE, endTime-time(0));
	}
	// 更新猜拳次数
	UpdateVIPValue(pChr, VIPMORRANUM, vipCard.morraNum);
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return;
	WorldPacket newP;
	if(CreateUpdateMorraNum(&newP, pChr))
		pSocket->SendPacket(&newP);
	// 更新VIP勋章图标
	if (vipCard.bShow)
		UpdateVIPData(pChr);
}
//-----------------------------------------------------------------------
void VipCardManager::RemoveVipInfo(CharPtr &pChr)
{
	if (pChr.isNull())
		return;
	{
		WGS_VIP_READ_LOCK
		std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
		for (; iter != m_mapVipCards.end(); ++iter)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > 0)
				pChr->user_data.Set<uint32>(iter->second.key, 0);
		}
	}
	UpdateVIPValue(pChr, VIPMORRANUM, 0);
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return;
	WorldPacket newP;
	if(CreateUpdateMorraNum(&newP, pChr))
		pSocket->SendPacket(&newP);
	// 更新VIP勋章图标
	UpdateVIPData(pChr);
}
//-----------------------------------------------------------------------
void VipCardManager::AddMorraNum(CharPtr &pChr, uint32 num)
{
	if (pChr.isNull())
		return;
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return;
	AddVipValue(pChr, VIPMORRANUM, num);
	WorldPacket packet;
	if(CreateUpdateMorraNum(&packet, pChr))
		pSocket->SendPacket(&packet);
}
//-----------------------------------------------------------------------
bool VipCardManager::Morra(CharPtr &pChr)
{
	if (pChr.isNull())
		return false;
	
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return false;
	
	uint32 leftNum = GetMorraLeftNum(pChr);
	if (!leftNum)
		return false;
	pChr->user_data.Set<uint32>(VIPMORRANUM, leftNum - 1);
	WorldPacket packet;
	if(CreateUpdateMorraNum(&packet, pChr))
		pSocket->SendPacket(&packet);
	
	return true;
}
//-----------------------------------------------------------------------
uint32 VipCardManager::GetMorraLeftNum(CharPtr &pChr)
{
	uint32 left = 0;
	if (!pChr.isNull())
		pChr->user_data.Get<uint32>(VIPMORRANUM, left);
	return left;
}
//-----------------------------------------------------------------------
bool VipCardManager::CreateUpdateMorraNum(WorldPacket * packet, CharPtr & pChr)
{
	if(pChr.isNull() || packet == NULL)
		return false;
	
	packet->clear();
	packet->reserve(24);
	packet->SetOpcode(SMSG_MORRA_UPDATENUM);
	*packet << uint16(SMSG_MORRA_UPDATENUM) << uint16(0)
			<< uint32(pChr->getHandle())
			<< uint32(GetMorraLeftNum(pChr));
	packet->SetLength(packet->size());
	return true;
}
//-----------------------------------------------------------------------
bool VipCardManager::GetVipXmlData(CharPtr & pChr, XMLDataSet & vipXml)
{
	if(pChr.isNull())
		return false;
	bool bFlag = false;
	std::map<uint32, VIPCard>::iterator mi, endmi = m_mapVipCards.end();
	for(mi = m_mapVipCards.begin(); mi != endmi; ++ mi)
	{
		if(pChr->user_data.isPresented(mi->second.key))
		{
			uint32 val = 0;
			pChr->user_data.Get<uint32>(mi->second.key, val);
			XMLData *pData = new XMLData(val,mi->second.key);
			vipXml.addXMLData(pData);
			bFlag = true;
		}
	}
	
	if(pChr->user_data.isPresented(VIPMORRANUM))
	{
		uint32 val = 0;
		pChr->user_data.Get<uint32>(VIPMORRANUM, val);
		XMLData *pData = new XMLData(val, VIPMORRANUM);
		vipXml.addXMLData(pData);	
		bFlag = true;
	}
	if(pChr->user_data.isPresented(LUCKY_EXPS))
	{
		uint32 val = 0;
		pChr->user_data.Get<uint32>(LUCKY_EXPS, val);
		XMLData *pData = new XMLData(val, LUCKY_EXPS);
		vipXml.addXMLData(pData);	
		bFlag = true;
	}
	if(pChr->user_data.isPresented(USERBUYVIP_TIME))
	{
		uint32 val = 0;
		pChr->user_data.Get<uint32>(USERBUYVIP_TIME, val);
		XMLData *pData = new XMLData(val, USERBUYVIP_TIME);
		vipXml.addXMLData(pData);	
		bFlag = true;
	}
	if(pChr->user_data.isPresented(TUHAO_EXPS))
	{
		uint32 val = 0;
		pChr->user_data.Get<uint32>(TUHAO_EXPS, val);
		XMLData *pData = new XMLData(val, TUHAO_EXPS);
		vipXml.addXMLData(pData);	
		bFlag = true;
	}
	if(pChr->user_data.isPresented(BODY_DATA))
	{
		String val;
		pChr->user_data.Get<String>(BODY_DATA, val);
		XMLData *pData = new XMLData(val, BODY_DATA);
		vipXml.addXMLData(pData);	
		bFlag = true;
	}
	
	return bFlag;
}
//-----------------------------------------------------------------------
void VipCardManager::SetVipXmlData(CharPtr & pChr, XMLDataSet & vipXml)
{
	if(pChr.isNull())
		return;
WGS_VIP_READ_LOCK
	std::map<uint32, VIPCard>::iterator mi, endmi = m_mapVipCards.end();
	for(mi = m_mapVipCards.begin(); mi != endmi; ++ mi)
	{		
		String key = mi->second.key;
		if(vipXml.isPresented(key))
		{// 设置新数据
			uint32 value = 0;
			vipXml.Get<uint32>(key, value);
			pChr->user_data.New<uint32>(key, value); 	
		}
	}	
	if(vipXml.isPresented(VIPMORRANUM))
	{// 这是个特殊的猜拳数量
		uint32 value = 0;
		vipXml.Get<uint32>(VIPMORRANUM, value);
		pChr->user_data.New<uint32>(VIPMORRANUM, value); 	
	}
	if(vipXml.isPresented(LUCKY_EXPS))
	{// 这是个特殊的幸运经验
		uint32 value = 0;
		vipXml.Get<uint32>(LUCKY_EXPS, value);
		pChr->user_data.New<uint32>(LUCKY_EXPS, value); 	
	}	
	if(vipXml.isPresented(USERBUYVIP_TIME))
	{
		uint32 value = 0;
		vipXml.Get<uint32>(USERBUYVIP_TIME, value);
		pChr->user_data.New<uint32>(USERBUYVIP_TIME, value); 
	}
	if(vipXml.isPresented(TUHAO_EXPS))
	{
		uint32 value = 0;
		vipXml.Get<uint32>(TUHAO_EXPS, value);
		pChr->user_data.New<uint32>(TUHAO_EXPS, value);
	}
	if(vipXml.isPresented(BODY_DATA))
	{
		String value;
		vipXml.Get<String>(BODY_DATA, value);
		pChr->user_data.New<String>(BODY_DATA, value); 
	}
}
//-----------------------------------------------------------------------
bool VipCardManager::ClearVipXmlData(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	bool bFlag = false;
	WGS_VIP_READ_LOCK
	// 置空旧数据
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if(pChr->user_data.isPresented(iter->second.key))
		{
			pChr->user_data.Set<uint32>(iter->second.key, 0);
			bFlag = true;
		}
	}
	
	return bFlag;
}
//-----------------------------------------------------------------------
bool VipCardManager::HaveVIPCard(CharPtr &pChr, const uint32 & vipid)
{
	if(pChr.isNull())
		return false;
	uint32 endTime = 0;
	pChr->user_data.Get<uint32>(VIPCARDDATE(vipid), endTime);
	return endTime > 0;
}
//-----------------------------------------------------------------------
uint32 VipCardManager::GetUsedVipId(CharPtr &pChr)
{
	if(pChr.isNull())
		return 0;
	WGS_VIP_READ_LOCK
	uint32 curTime = time(0);
	uint32 maxVipId = 0; // 最高vip等级
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (1 == iter->second.type)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > curTime)
				maxVipId = iter->first;
		}
	}
	return maxVipId;
}

uint32 VipCardManager::GetUsedVipId(XMLDataSet &user_data)
{
	uint32 curTime = time(0);
	uint32 maxVipId = 0; // 最高vip等级
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (1 == iter->second.type)
		{
			uint32 endTime = 0;
			if (user_data.Get<uint32>(iter->second.key, endTime) && endTime > curTime)
				maxVipId = iter->first;
		}
	}
	return maxVipId;
}
//-----------------------------------------------------------------------
void VipCardManager::GetWelfareList(std::list<VIPCard> &lstWelfare)
{
	WGS_VIP_READ_LOCK
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (4 == iter->second.type)
		{
			lstWelfare.push_back(iter->second);
		}
	}
}
//-----------------------------------------------------------------------
uint32 VipCardManager::GetSelfWelfareList(CharPtr &pChr, std::list<VIPCard> &lstWelfare)
{
	if(pChr.isNull())
		return 0;
	WGS_VIP_READ_LOCK
	uint32 allCoins = 0;
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (4 == iter->second.type)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > 0)
			{
				allCoins += iter->second.lgAdd;
				lstWelfare.push_back(iter->second);
			}
		}
	}
	return allCoins;
}
//-----------------------------------------------------------------------
bool VipCardManager::HaveWelfare(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	WGS_VIP_READ_LOCK
	std::map<uint32, VIPCard>::iterator iter = m_mapVipCards.begin();
	for (; iter != m_mapVipCards.end(); ++iter)
	{
		if (4 == iter->second.type)
		{
			uint32 endTime = 0;
			if (pChr->user_data.Get<uint32>(iter->second.key, endTime) && endTime > 0)
			{
				return true;
			}
		}
	}
	return false;
}

